﻿#region Using Directives

    using System;
    using System.Collections.Generic;
    using System.Security.Principal;

    using Csla;
    using Csla.Security;

    using MarketPulse.BusinessLogic.Core.System;

#endregion

namespace MarketPulse.BusinessLogic.Core.Security
{
    [Serializable]
    internal class MarketPulsePrincipal : CslaPrincipal
    {
        #region Member Variables

            /// <summary>The audit object to use to audit the user login attempt</summary>
            //private AuditUserLogin auditUserLogin;

        #endregion

        #region Constructors

        /// <summary>
            /// Default constructor is private in order to (try to) enforce construction
            /// only via the static factory methods provided.
            /// </summary>
            private MarketPulsePrincipal(IIdentity identity) : base(identity)
            {
            }

        #endregion

        #region Methods

            /// <summary>
            /// Method used to attempt the login of a user based on the username and password supplied
            /// </summary>
            /// <param name="username">The username to use as part of the login attempt</param>
            /// <param name="password">The password to use as part of the login attempt</param>
            /// <param name="profileTypeGUID">The type of profile to use as part of the login attempt</param>
            /// <returns>Returns a valid (Read Only) user or null</returns>
            public static ApplicationProfile Login(string username, string password, Guid profileTypeGUID)
            {
                return Login(username, password, profileTypeGUID, null, null);
            }

            /// <summary>
            /// Method used to attempt the login of a user based on the username and password supplied
            /// </summary>
            /// <param name="userGUID">The UserGUID to use as part of the login attempt</param>
            /// <param name="privateKey">The private key to use as part of the login attempt</param>
            /// <param name="profileTypeGUID">The type of profile to use as part of the login attempt</param>
            /// <returns>Returns a valid (Read Only) user or null</returns>
            public static ApplicationProfile Login(Guid userGUID, string privateKey, Guid profileTypeGUID)
            {
                return Login(null, null, profileTypeGUID, userGUID, privateKey);
            }

            /// <summary>
            /// Method used to log a user out
            /// </summary>
            public static void Logout()
            {
                var identity = new UnauthenticatedIdentity();
                var principle = new MarketPulsePrincipal(identity);
                Csla.ApplicationContext.User = principle;
            }

            /// <summary>
            /// Method used to attempt the login of a user based on the username and password supplied
            /// </summary>
            /// <param name="username">The username to use as part of the login attempt</param>
            /// <param name="password">The password to use as part of the login attempt</param>
            /// <param name="profileTypeGUID">The type of profile to use as part of the login attempt</param>
            /// <param name="userGUID">The UserGUID to use as part of the login attempt</param>
            /// <param name="privateKey">The private key to use as part of the login attempt</param>
            /// <returns>Returns a valid (Read Only) user or null</returns>
            private static ApplicationProfile Login(string username, string password, Guid profileTypeGUID, Nullable<Guid> userGUID, string privateKey)
            {
                // Ensure that the ApplicationContext user
                // is actually UnauthenticatedPrincipal and
                // not null to ensure that remote requests
                // prior to successfully authenticating are
                // issued with this non-null principal.
                Csla.ApplicationContext.User = new UnauthenticatedPrincipal();

                MarketPulseIdentity identity = null;
                if (userGUID.HasValue)
                {
                    identity = MarketPulseIdentity.Get(userGUID.Value, privateKey, profileTypeGUID);
                }
                else
                {
                    identity = MarketPulseIdentity.Get(username, password, profileTypeGUID);
                }

                var principle = new MarketPulsePrincipal(identity);
                Csla.ApplicationContext.User = principle;

                ApplicationProfile profile = null;

                // If authentication is successful, get the return user
                if (identity.IsAuthenticated)
                {
                    profile = ApplicationProfile.Get(identity.Name, profileTypeGUID);
                }

                return profile;
            }

        #endregion

    }
}